﻿using ReactiveUI;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Avalonia.Media.Imaging;
using AutojsController.Services;
using AutojsController.Helpers;
using AutojsController.Config;
using System.Diagnostics;
using Serilog;

namespace AutojsController.ViewModels
{

    public class MobileItemViewModel:ReactiveObject
    {
        private Mobile _mobile;
        public Mobile Mobile
        {
            get => _mobile;
            set
            {
                _mobile = value;
                this.RaisePropertyChanged(nameof(Mobile));
                this.RaisePropertyChanged(nameof(Icon));
            }
        }

        private MobileStatus _status;
        public MobileStatus Status {
            get => _status;
            set
            {
                _status = value;
                this.RaisePropertyChanged(nameof(Status));
                this.RaisePropertyChanged(nameof(StatusIcon));
                this.RaisePropertyChanged(nameof(StatusText));
                this.RaisePropertyChanged(nameof(ButtonEnabled));
                this.RaisePropertyChanged(nameof(ActionName));
                this.RaisePropertyChanged(nameof(ButtonAction));
            }
        }

        private string _operationInfo = "";
        public string OperationInfo
        {
            get => _operationInfo;
            set => this.RaiseAndSetIfChanged(ref _operationInfo, value);
        }

        public Bitmap? Icon
        {
            get
            {
                return Image.LoadFromResource(
                    Mobile.DeviceType?.ToLower() switch
                    {
                        _ => "/Assets/Icons/unkownDevice.jpeg",
                    }
                );
            }
        }

        public Bitmap? StatusIcon
        {
            get
            {
                return Image.LoadFromResource(
                    _status switch
                    {
                        MobileStatus.Connected => "/Assets/Icons/connected.png",
                        MobileStatus.Running => "/Assets/Icons/running.png",
                        MobileStatus.Connecting => "/Assets/Icons/operating.png",
                        MobileStatus.Stopping => "/Assets/Icons/operating.png",
                        MobileStatus.ForceStopping => "/Assets/Icons/operating.png",
                        _ => "/Assets/Icons/disconnected.png",
                    }
                );
            }
        }

        public string StatusText
        {
            get
            {
                return _status switch
                {
                    MobileStatus.Connected => "已连接",
                    MobileStatus.Running => "运行中",
                    MobileStatus.Connecting => "连接中",
                    MobileStatus.Stopping => "停止中",
                    MobileStatus.ForceStopping => "强制停止中",
                    _ => "未连接",
                };
            }
        }

        public Boolean ButtonEnabled
        {
            get
            {
                return _status == MobileStatus.Disconnected || _status == MobileStatus.Connected || _status == MobileStatus.Running;
            }
        }

        public string ActionName
        {
            get
            {
                switch (_status)
                {
                    case MobileStatus.Connected:
                        return "断开";
                    case MobileStatus.Running:
                        return "停止";
                    case MobileStatus.Connecting:
                        return "连接中";
                    case MobileStatus.Stopping:
                        return "停止中";
                    default:
                        return "连接";
                }
            }
        }

        public ICommand ButtonCommand { get; }

        public MobileAction ButtonAction
        {
            get
            {
                switch (_status)
                {
                    case MobileStatus.Connected:
                        return MobileAction.Disconnect;
                    case MobileStatus.Running:
                        return MobileAction.Stop;
                    case MobileStatus.Disconnected:
                        return MobileAction.Connect;
                    default:
                        return MobileAction.None;
                }
            }
        }

        private bool _isSelected;

        public bool IsSelected
        {
            get => _isSelected;
            set => this.RaiseAndSetIfChanged(ref _isSelected, value);
        }

        public MobileConnectionService? connection;
        private readonly ILogger logger;

        public MobileItemViewModel(Mobile mobile)
        {
            this._mobile = mobile;
            logger = LoggerFactory.GetLogger($"device({mobile.Address.Replace(".", "_")})");
            ButtonCommand = ReactiveCommand.CreateFromTask<MobileAction>(ButtonActionAsync);
        }

        public void updateMobile(Mobile mobile)
        {
            this.Mobile = mobile;
        }

        private async Task ButtonActionAsync(MobileAction action)
        {
            switch (action)
            {
                case MobileAction.Connect:
                    await ConnectAction();
                    break;
                case MobileAction.Disconnect:
                    await DisconnectAction();
                    break;
                case MobileAction.Stop:
                    await StopAction();
                    break;
                case MobileAction.ForceStop:
                    await ForceStopAction();
                    break;
            }
        }

        public async Task ConnectAction()
        {
            logger.Information("开始连接");
            if (this.Status == MobileStatus.Connected) return;
            if (this.connection == null)
            {
                try
                {
                    this.Status = MobileStatus.Connecting;
                    this.OperationInfo = "正在连接...";
                    this.connection = await MobileConnectionService.CreateAndConnect(this.Mobile.Address);
                    if (this.connection == null) throw new Exception("设备无响应");
                    this.connection.MessageReceived += this.HandleConnectionMessage;
                }
                catch(Exception ex)
                {
                    logger.Error(ex, "连接异常");
                    this.Status = MobileStatus.Disconnected;
                    this.OperationInfo = "连接失败";
                    return;
                }
            }
            try
            {
                if (this.Status != MobileStatus.Connecting)
                {
                    this.Status = MobileStatus.Connecting;
                    this.OperationInfo = "正在连接...";
                }
                await connection.sendHello();
            }
            catch(Exception ex)
            {
                logger.Error(ex, "连接异常");
                this.Status = MobileStatus.Disconnected;
                this.OperationInfo = "连接失败";
            }
        }

        public async Task DisconnectAction()
        {
            logger.Information("断开连接");
            if (this.Status == MobileStatus.Disconnected) return;
            if (this.connection == null) return;
        }

        public async Task StopAction()
        {
            logger.Information("停止任务");
            if (this.Status != MobileStatus.Running) return;
        }

        public async Task ForceStopAction()
        {
            logger.Information("强制停止任务");
            if (this.Status != MobileStatus.Stopping) return;
        }

        public void HandleConnectionMessage(MobileConnectionService mcs, MessageEventArgs message)
        {
            var data = message.data;
            logger.Information($"设备响应:{data}");
            if (!data.ContainsKey("type") && !data.ContainsKey("data")) return;
            switch (data["type"]?.ToString())
            {
                case "hello":
                    this.Status = MobileStatus.Connected;
                    this.OperationInfo = "";
                    break;
                default:
                    //Debug.WriteLine($"接收到一个{data["type"]}消息类型, 内容为:{data["data"]}");
                    break;
            }
        }
    }
}
